﻿using SimpleBoard.Behavior;
using SimpleBoard.Compiler;
using SimpleBoard.DependencyInjection;
using SimpleBoard.Designer.Extensions;
using SimpleBoard.Project;
using SimpleBoard.Project.Binding;
using SimpleBoard.Project.Data;
using SimpleBoard.Project.UI;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;

namespace SimpleBoard.Designer.Services
{
    [InjectAs(InjectionType.Singleton)]
    public class ProjectService
    {
        private readonly ControllerService controllerService;
        public ProjectService(ControllerService controllerService)
        {
            this.controllerService = controllerService;
        }

        public ProjectInfo ParseProject(Panel uiRoot, IEnumerable<DataUnit> dataUnits, IEnumerable<DataBinding> dataBindings)
        {
            var controlInfoList = new List<ControlInfo>();

            foreach (FrameworkElement control in uiRoot.Children)
            {
                var element = (control as Border)!.Child as FrameworkElement;

                // 获取关联的Behavior
                var behavior = Microsoft.Xaml.Behaviors.Interaction.GetBehaviors(element)
                    .Where(x => x.GetType() == typeof(TranslateZoomBehavior))
                    .Cast<TranslateZoomBehavior>()
                    .Single();

                // 获取控件元信息
                var controlMeta = controllerService.GetControllerInfo(element!);

                var controlInfo = new ControlInfo
                {
                    Name = element!.Name,
                    AssemblyFullName = controlMeta.AssemblyFullName,
                    TypeFullName = controlMeta.TypeFullName,
                    Height = (int)behavior.Size.Height,
                    Width = (int)behavior.Size.Width,
                    Left = (int)behavior.Position.X,
                    Top = (int)behavior.Position.Y,
                    Properties = new Dictionary<string, object>(
                        controlMeta.Properties.Select(x => new KeyValuePair<string, object>(x.Name, element!.GetPropertyValue(x.Name)!))),
                };

                controlInfoList.Add(controlInfo);
            }
            var pageInfo = new PageInfo
            {
                Width = (int)uiRoot.Width,
                Height = (int)uiRoot.Height,
                // TODO 获取背景色
                BackgroundColor = "#00002B",
                Controls = controlInfoList,
            };
            var projectInfo = new ProjectInfo
            {
                Page = pageInfo,
                DataFrameMeta = new DataFrameMeta
                {
                    DataUnits = dataUnits.ToArray(),
                },
                 DataBindings = dataBindings.ToArray(),
            };

            return projectInfo;
        }

        public CompileResult CompileProject(ProjectInfo project)
        {
            var compiler = new ProjectCompiler(project);
            return compiler.Compile();
        }

        public void SaveProject(ProjectInfo project)
        {
            var projectJson = Serializer.Serialize(project);
            if (File.Exists("project.json")) File.Delete("project.json");
            using var file = File.OpenWrite("project.json");
            using var writer = new StreamWriter(file);
            writer.Write(projectJson);
            writer.Flush();
            writer.Close();
        }

        public ProjectInfo? LoadProject()
        {
            if (!File.Exists("project.json")) return null;
            using var file = File.OpenRead("project.json");
            using var reader = new StreamReader(file);
            var projectJson = reader.ReadToEnd();
            var project = Serializer.Deserialize(projectJson);
            return project;
        }
    }
}
